package moonlit.chill.pay.service.impl.wechat;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.QueryByOutRefundNoRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.Status;
import lombok.extern.slf4j.Slf4j;
import moonlit.chill.pay.cache.PayConfigDataCache;
import moonlit.chill.pay.constants.Constants;
import moonlit.chill.pay.service.PayStrategy;
import moonlit.chill.pay.util.WxConfigUtil;
import moonlit.chill.pay.vo.PayConfig;
import moonlit.chill.pay.vo.PayResult;
import moonlit.chill.pay.vo.RefundResult;
import moonlit.chill.pay.vo.TradeParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @author MoonlitChill
 * @date 2024/4/16 14:27
 */
@Slf4j
@Service("wxRefundQueryStrategy")
public class WxRefundQueryStrategyServiceImpl implements PayStrategy {

    @Resource
    private PayConfigDataCache payConfigDataCache;

    @Autowired
    private WxConfigUtil wxConfigUtil;

    private static final String TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";

    @Override
    public PayResult<?> payForRefundQuery(TradeParam tradeParam) {
        PayResult<String> result = new PayResult<>();
        PayConfig payConfig = payConfigDataCache.getPayConfig();
        Config config = wxConfigUtil.getConfig(payConfig);
        QueryByOutRefundNoRequest refundQuery = new QueryByOutRefundNoRequest();
        refundQuery.setOutRefundNo(tradeParam.getRefundNo());
        RefundService service = new RefundService.Builder().config(config).build();
        Refund refund = service.queryByOutRefundNo(refundQuery);
        if (ObjectUtil.isNotEmpty(refund)) {
            RefundResult refundResult = new RefundResult();
            Status status = refund.getStatus();
            refundResult.setTransNum(refund.getOutTradeNo());
            refundResult.setRefundNo(refund.getRefundId());
            refundResult.setOutTradeNo(refund.getTransactionId());
            refundResult.setOutRefundNo(refund.getOutRefundNo());
            Long refundFee = refund.getAmount().getRefund();
            BigDecimal amountPay = (new BigDecimal(refundFee).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            refundResult.setRefundFee(amountPay);
            refundResult.setRefundStatus(status.name());
            if (status.equals(Status.SUCCESS)) {
                result.setSuccess(Boolean.TRUE);
                refundResult.setRefundTime(DateUtil.format(DateUtil.parse(refund.getSuccessTime(), TIME_FORMAT), DatePattern.NORM_DATETIME_PATTERN));
            } else if (status.equals(Status.PROCESSING)) {
                result.setSuccess(Boolean.TRUE);
                refundResult.setRefundTime(DateUtil.format(DateUtil.parse(refund.getCreateTime(), TIME_FORMAT), DatePattern.NORM_DATETIME_PATTERN));
            } else {
                result.error("退款异常，请联系管理员", Constants.PAY_FAIL_CODE);
            }
            result.setResult(JSONUtil.toJsonStr(refundResult));
        } else {
            result.error("退款查询异常，请联系管理员", Constants.PAY_FAIL_CODE);
        }
        return result;
    }
}
